البرمجة

تطبيق البرمجة الكائنية بـ #C

تطبيق البرمجة كائنية التوجه في لغة سي شارب #C – الجزء الثالث

تمثل البرمجة كائنية التوجه (Object-Oriented Programming – OOP) أحد الأسس الأساسية التي ترتكز عليها لغات البرمجة الحديثة، ومن بينها لغة #C‎. تعد هذه المنهجية إطارًا فكريًا وتنظيميًا لبناء التطبيقات الكبيرة والمعقدة عبر تقسيمها إلى كيانات منطقية مستقلة تعرف بالكائنات (Objects). وبعد استعراض المفاهيم التمهيدية في الجزأين الأول والثاني، يركز هذا الجزء الثالث على التطبيق العملي المكثف والمفصل لمنهجية البرمجة الكائنية باستخدام لغة #C‎، ويغوص عميقًا في مفاهيم الوراثة المتعددة، تعدد الأشكال (Polymorphism)، والواجهات (Interfaces)، مع تطبيقات عملية واقعية.


الوراثة المتقدمة في لغة #C

الوراثة الأحادية

تدعم #C الوراثة الأحادية (Single Inheritance)، حيث يمكن للفئة (Class) أن ترث من فئة واحدة فقط. تعتبر هذه الآلية حجر الزاوية في إعادة الاستخدام وإعادة التنظيم البنيوي للكود.

csharp
public class Person { public string Name { get; set; } public void Speak() { Console.WriteLine("I am a person."); } } public class Student : Person { public int Grade { get; set; } }

هنا ترث Student الخصائص والسلوكيات من Person، مما يجعل الكود أكثر اختصارًا ومرونة.

الوراثة من خلال الواجهات

بما أن #C لا تدعم الوراثة المتعددة مباشرة، فإن استخدام الواجهات يوفر طريقة بديلة لدعم هذا النمط.

csharp
public interface IWorker { void Work(); } public interface IStudent { void Study(); } public class WorkingStudent : IWorker, IStudent { public void Work() => Console.WriteLine("Working..."); public void Study() => Console.WriteLine("Studying..."); }

هنا يقوم الكائن WorkingStudent بتطبيق كل من واجهتي IWorker وIStudent، محققًا بذلك سلوكًا متعدد الجوانب دون اللجوء إلى وراثة متعددة تقليدية.


تعدد الأشكال Polymorphism

يعتبر تعدد الأشكال من المبادئ الأساسية للبرمجة الكائنية، ويتيح استبدال كائنات من أنواع فرعية في أماكن تُستخدم فيها أنواع أساسية، دون الإخلال بوظيفة النظام.

تعدد الأشكال عبر الوراثة

csharp
public class Animal { public virtual void Speak() { Console.WriteLine("Animal sound"); } } public class Dog : Animal { public override void Speak() { Console.WriteLine("Bark"); } } public class Cat : Animal { public override void Speak() { Console.WriteLine("Meow"); } }
csharp
List animals = new List { new Dog(), new Cat() }; foreach (var animal in animals) { animal.Speak(); // ستُستدعى الطريقة الصحيحة حسب نوع الكائن الحقيقي }

يسمح هذا النمط بكتابة كود عام يمكنه التعامل مع فئات متعددة بشكل ديناميكي.

استخدام الكلمة المحجوزة abstract

تستخدم الفئات المجردة لتعريف سلوكيات مشتركة دون إعطاء تفاصيل التنفيذ، على أن تترك مهمة التنفيذ للفئات المشتقة.

csharp
public abstract class Shape { public abstract double GetArea(); } public class Circle : Shape { public double Radius { get; set; } public override double GetArea() => Math.PI * Radius * Radius; } public class Square : Shape { public double Side { get; set; } public override double GetArea() => Side * Side; }

الواجهات Interfaces وتطبيقاتها المتقدمة

تعريف الواجهات

الواجهة هي عقد يحدد مجموعة من الوظائف التي يجب على الفئة التي تطبقها أن تنفذها.

csharp
public interface ILogger { void Log(string message); }

تطبيق عملي: إدارة نظام تسجيل

csharp
public class FileLogger : ILogger { public void Log(string message) { File.AppendAllText("log.txt", message + Environment.NewLine); } } public class DatabaseLogger : ILogger { public void Log(string message) { // تخيل هنا كود يقوم بإضافة السجل إلى قاعدة بيانات } } public class RegistrationService { private readonly ILogger _logger; public RegistrationService(ILogger logger) { _logger = logger; } public void RegisterUser(string username) { // كود التسجيل... _logger.Log("User registered: " + username); } }

من خلال الاعتماد على الواجهة، يمكن تغيير طريقة تسجيل البيانات (ملف، قاعدة بيانات، بريد إلكتروني) دون تغيير الكود الداخلي لخدمة التسجيل.


المبادئ SOLID في تصميم الكائنات

مبدأ المسؤولية الواحدة (SRP)

ينص هذا المبدأ على أن كل فئة يجب أن تقوم بمهمة واحدة فقط.

csharp
public class Invoice { public void CalculateTotal() { /* حساب المجموع */ } } public class InvoicePrinter { public void PrintInvoice(Invoice invoice) { /* طباعة */ } }

مبدأ الانفتاح/الإغلاق (OCP)

يجب أن تكون الكائنات قابلة للامتداد ولكن غير قابلة للتعديل.

csharp
public abstract class Discount { public abstract decimal Calculate(decimal price); } public class NoDiscount : Discount { public override decimal Calculate(decimal price) => price; } public class PercentageDiscount : Discount { public override decimal Calculate(decimal price) => price * 0.9m; }

استخدام الأنماط التصميمية (Design Patterns)

نمط المصنع (Factory Pattern)

يساعد على إنشاء كائنات دون تحديد النوع الحقيقي مباشرةً.

csharp
public interface IShape { void Draw(); } public class Circle : IShape { public void Draw() => Console.WriteLine("Drawing Circle"); } public class ShapeFactory { public static IShape GetShape(string type) { return type switch { "circle" => new Circle(), _ => throw new ArgumentException("Unknown type") }; } }

نمط المراقب (Observer Pattern)

يستخدم لمراقبة الأحداث والاستجابة لها في كائنات متعددة.

csharp
public interface IObserver { void Update(string message); } public class User : IObserver { public void Update(string message) => Console.WriteLine("Received: " + message); } public class NotificationService { private List observers = new(); public void Subscribe(IObserver observer) => observers.Add(observer); public void Notify(string message) { foreach (var observer in observers) observer.Update(message); } }

جدول يوضح الفروق بين المفاهيم الكائنية الرئيسية

المفهوم التعريف المثال في #C
الوراثة قدرة الفئة على استيراث خصائص وسلوك فئة أخرى class Student : Person
تعدد الأشكال سلوك مختلف لنفس النداء حسب نوع الكائن animal.Speak() قد تُنتج “Meow” أو “Bark”
التجريد إخفاء تفاصيل التنفيذ وتوفير واجهة فقط abstract class Shape { abstract GetArea(); }
الواجهة عقد للسلوكيات دون تنفيذ interface ILogger { void Log(string message); }
المسؤولية الواحدة كل فئة تؤدي وظيفة واحدة فقط Invoice و InvoicePrinter كمثالين مستقلين

المعالجة الفعالة للأخطاء في بيئة OOP

التعامل مع الأخطاء جزء لا يتجزأ من تطبيق OOP، وذلك باستخدام الكتل try-catch لضمان سلامة التطبيق.

csharp
try { var result = 10 / int.Parse("0"); } catch (DivideByZeroException ex) { Console.WriteLine("Cannot divide by zero."); } catch (Exception ex) { Console.WriteLine("General error: " + ex.Message); }

اختبار الوحدات في سياق OOP

يعزز تصميم الكائنات الجيد القدرة على اختبار الوحدات (Unit Testing) بشكل فعال.

csharp
public class Calculator { public int Add(int a, int b) => a + b; }
csharp
[TestMethod] public void Add_TwoNumbers_ReturnsSum() { var calc = new Calculator(); var result = calc.Add(2, 3); Assert.AreEqual(5, result); }

الخلاصة التنفيذية

تمثل البرمجة كائنية التوجه جوهر تطوير البرمجيات الحديثة، وقد مكنت مطوري #C من بناء نظم كبيرة وقابلة للصيانة والتوسع. يتطلب التطبيق الناجح لهذه المبادئ فهماً عميقاً للوراثة، الواجهات، التجريد، وتعدد الأشكال، إلى جانب اعتماد المبادئ التصميمية والأنماط المؤسسية الفعالة. إن حسن توظيف هذه التقنيات ينتج عنه برمجيات قوية، مرنة، وتتماشى مع متطلبات المستقبل الرقمي.


المراجع:

  1. Microsoft Docs – C# Programming Guide. https://learn.microsoft.com/en-us/dotnet/csharp/

  2. Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software.